﻿#region Librerias

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using ESF.General;
using System.Windows;
using System.Windows.Threading;
using System.Windows.Media;

#endregion


namespace ESF.WinForms
{
	public static class WPFHelper
	{
		#region XAML

		public static DependencyObject GetParentObject(this DependencyObject child)
		{
			if (child == null) return null;

			//handle content elements separately
			ContentElement contentElement = child as ContentElement;
			if (contentElement != null)
			{
				DependencyObject parent = ContentOperations.GetParent(contentElement);
				if (parent != null) return parent;

				FrameworkContentElement fce = contentElement as FrameworkContentElement;
				return fce != null ? fce.Parent : null;
			}

			//also try searching for parent in framework elements (such as DockPanel, etc)
			FrameworkElement frameworkElement = child as FrameworkElement;
			if (frameworkElement != null)
			{
				DependencyObject parent = frameworkElement.Parent;
				if (parent != null) return parent;
			}

			//if it's not a ContentElement/FrameworkElement, rely on VisualTreeHelper
			return VisualTreeHelper.GetParent(child);
		}

		public static T TryFindParent<T>(this DependencyObject child) where T : DependencyObject
		{
			//get parent item
			DependencyObject parentObject = GetParentObject(child);

			//we've reached the end of the tree
			if (parentObject == null) return null;

			//check if the parent matches the type we're looking for
			T parent = parentObject as T;
			if (parent != null)
			{
				return parent;
			}
			else
			{
				//use recursion to proceed with next level
				return TryFindParent<T>(parentObject);
			}
		}

		#endregion


		#region Asignadores

		public static void SetEnabled (Control pControl, bool pIsEnabled = true)
		{
			pControl.Dispatcher.Invoke ((Action) delegate () { pControl.IsEnabled = pIsEnabled; });
		}


		public static void SetTitle (Window pWindow, string pTitle)
		{
			pWindow.Dispatcher.Invoke ((Action) delegate () { pWindow.Title = pTitle; });
		}


		public static void ClearTitle (Window pWindow)
		{
			SetTitle (pWindow, string.Empty);
		}


		public static string GetText(Label pLabel)
		{
			return pLabel.Dispatcher.Invoke((Func<string>)
				(() =>
				{
					return pLabel.Content.ToString();
				})) as string;
		}


		public static string GetText(TextBox pText)
		{
			return pText.Dispatcher.Invoke((Func<string>)
				(() =>
				{
					return pText.Text;
				})) as string;
		}


		public static string GetText(TextBlock pText)
		{
			return pText.Dispatcher.Invoke((Func<string>)
				(() =>
				{
					return pText.Text;
				})) as string;
		}

		
		public static string GetPassword (PasswordBox pText)
		{
			return pText.Dispatcher.Invoke((Func<string>)
				(() =>
				{
					return pText.Password;
				})) as string;
		}
		

		public static void SetText (Label pLabel, string pMessage)
		{
			pLabel.Dispatcher.Invoke ((Action) delegate () { pLabel.Content = pMessage; });
		}


		public static void SetText(TextBox pText, string pMessage)
		{
			pText.Dispatcher.Invoke((Action)delegate() { pText.Text = pMessage; });
		}


		public static void SetText(TextBlock pText, string pMessage)
		{
			pText.Dispatcher.Invoke((Action)delegate() { pText.Text = pMessage; });
		}


		public static void ClearPassword(PasswordBox pPasBox)
		{
			Dispatcher.CurrentDispatcher.Invoke(
				(Action)(() =>
				{
					pPasBox.Password = string.Empty;
				}));
		}


		public static void ClearText (Label pLabel)
		{
			SetText (pLabel, string.Empty);
		}


		public static void SetAdvance(Label pLabel, ProgressBar pProgressBar, string pMessage = "", int pTotalWorkCount = 0, int pReadyWorkCount = 0, int pTotalErrors = 0, long pItemElapsedMs = 0)
		{
			double advance100;


			advance100 = ProcessHelper.GetAdvancePercentage100 (pTotalWorkCount, pReadyWorkCount + pTotalErrors);

			SetText (pLabel, 
				(string.IsNullOrEmpty (pMessage) ? string.Empty : pMessage + "... ") + 
				string.Format ("Procesados {0} de {1}{3}: {2:0.##}%", pReadyWorkCount, pTotalWorkCount, advance100, 
				(pTotalErrors > 0 ? string.Format (" con {0} errores", pTotalErrors) : string.Empty)));
			
			SetValue (pProgressBar, advance100);
		}


		public static void ClearAdvance (Label pLabel, ProgressBar pProgressBar)
		{
			ClearText (pLabel);
			ClearValue (pProgressBar);
		}


		public static void ClearValue (ProgressBar pProgressBar)
		{
			SetValue (pProgressBar, 0);
		}


		public static void SetValue (ProgressBar pProgressBar, double pValue)
		{
			pProgressBar.Dispatcher.Invoke ((Action) delegate () { pProgressBar.Value = (int) pValue; });
		}


		public static void Focus (Control pControl)
		{
			pControl.Dispatcher.Invoke(
				(Action)(() =>
				{
					pControl.Focus();
				}));
		}

		#endregion
	}
}
